﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using MDT.LifeSewagePlatform.Conmmon;
using MDT.LifeSewagePlatform.Entity;
using MDT.LifeSewagePlatform.IRepository;
using Microsoft.EntityFrameworkCore;

namespace MDT.LifeSewagePlatform.Repository
{
    public class DrugRepository : BaseRepository<DrugEntity>, IDrugRepository
    {
        [Autowired]
        public SystemConfigEntity systemConfig { get; set; }
        public DrugRepository()
        {
        }


        public IQueryable<DrugUnion> GetDrugDto(Expression<Func<DrugUnion, bool>> expression)
        {
            var query = from drug in _dbContext.Drug.AsNoTracking()
                        join file in _dbContext.Files.AsNoTracking() on drug.FileID equals file.ID 
                        join area in _dbContext.Regions.AsNoTracking() on drug.AreaID equals area.ID into LeftArea
                        from leftarea in LeftArea.DefaultIfEmpty()
                        join city in _dbContext.Regions.AsNoTracking() on file.CityID equals city.ID
                        select new DrugUnion
                        {

                            Morphine = Math.Round(drug.Morphine,2),
                            Codeine = Math.Round(drug.Codeine,2),
                            Methcathinone =Math.Round(drug.Methcathinone,2),
                            Monoacetylmorphine_06 =Math.Round(drug.Monoacetylmorphine_06,2),
                            Benzedrine =Math.Round(drug.Benzedrine,2),
                            Methylamphetamine =Math.Round(drug.Methylamphetamine,2),
                            PMMA =Math.Round(drug.PMMA,2),
                            Ketamine =Math.Round(drug.Ketamine,2),
                            NoKetamine =Math.Round(drug.NoKetamine,2),
                            Cyclohexanone =Math.Round(drug.Cyclohexanone,2),
                            MDA =Math.Round(drug.MDA,2),
                            MDMA =Math.Round(drug.MDMA,2),
                            Benzoylecgonine =Math.Round(drug.Benzoylecgonine,2),
                            Cocaine =Math.Round(drug.Cocaine,2),
                            Cotinine = Math.Round(drug.Cotinine,2),
                            MonitoringSite = drug.MonitoringSite,
                            AreaID = drug.AreaID,
                            Quarter = drug.Quarter,
                            CompanyID = drug.CompanyID,
                            CityID = file.CityID,
                            AreaName = leftarea==null ? "无":leftarea.DisplayName,
                            MonitorTime = drug.MonitorTime,
                            CityName = city.DisplayName
                        };
            return query.Where(expression);
        }

        public IQueryable<DrugView> GroupByDrug(IQueryable<DrugUnion> drugUnion)
        {
            return drugUnion.GroupBy(d => d.MonitoringSite).Select(d => new DrugView()
            {
                Morphine = d.Average(t => t.Morphine),
                Codeine = d.Average(t => t.Codeine),
                Methcathinone = d.Average(t => t.Methcathinone),
                Monoacetylmorphine_06 = d.Average(t => t.Monoacetylmorphine_06),
                Benzedrine = d.Average(t => t.Benzedrine),
                Methylamphetamine = d.Average(t => t.Methylamphetamine),
                PMMA = d.Average(t => t.PMMA),
                Ketamine = d.Average(t => t.Ketamine),
                NoKetamine = d.Average(t => t.NoKetamine),
                Cyclohexanone = d.Average(t => t.Cyclohexanone),
                MDA = d.Average(t => t.MDA),
                MDMA = d.Average(t => t.MDMA),
                Benzoylecgonine = d.Average(t => t.Benzoylecgonine),
                Cocaine = d.Average(t => t.Cocaine),
                Cotinine = d.Average(t => t.Cotinine),
                MonitoringSite = d.Key,
            });
        }

        public async Task<List<DrugReport>> GroupDrug(IQueryable<DrugUnion> drugUnion)
        {
            if (systemConfig.QuarterOrMonth == (int)eGroupGetDateType.Quarter)
            {
                return await drugUnion.GroupBy(t => new { t.CityName, t.AreaName, t.MonitoringSite, t.AreaID, t.Quarter }).Select(d => new DrugReport()
                {
                    Morphine = d.Average(t => t.Morphine),
                    Codeine = d.Average(t => t.Codeine),
                    Methcathinone = d.Average(t => t.Methcathinone),
                    Monoacetylmorphine_06 = d.Average(t => t.Monoacetylmorphine_06),
                    Benzedrine = d.Average(t => t.Benzedrine),
                    Methylamphetamine = d.Average(t => t.Methylamphetamine),
                    PMMA = d.Average(t => t.PMMA),
                    Ketamine = d.Average(t => t.Ketamine),
                    NoKetamine = d.Average(t => t.NoKetamine),
                    Cyclohexanone = d.Average(t => t.Cyclohexanone),
                    MDA = d.Average(t => t.MDA),
                    MDMA = d.Average(t => t.MDMA),
                    Benzoylecgonine = d.Average(t => t.Benzoylecgonine),
                    Cocaine = d.Average(t => t.Cocaine),
                    Cotinine = d.Average(t => t.Cotinine),
                    MonitoringSite = d.Key.MonitoringSite,
                    CityName = d.Key.CityName,
                    AreaName = d.Key.AreaName,
                    AreaID = d.Key.AreaID,
                    Quarter = d.Key.Quarter
                }).ToListAsync();
            }

            if (systemConfig.QuarterOrMonth == (int)eGroupGetDateType.Month)
            {
                return await drugUnion.GroupBy(t => new { t.CityName, t.AreaName, t.MonitoringSite, t.AreaID, t.MonitorTime.Month }).Select(d => new DrugReport()
                {
                    Morphine = d.Average(t => t.Morphine),
                    Codeine = d.Average(t => t.Codeine),
                    Methcathinone = d.Average(t => t.Methcathinone),
                    Monoacetylmorphine_06 = d.Average(t => t.Monoacetylmorphine_06),
                    Benzedrine = d.Average(t => t.Benzedrine),
                    Methylamphetamine = d.Average(t => t.Methylamphetamine),
                    PMMA = d.Average(t => t.PMMA),
                    Ketamine = d.Average(t => t.Ketamine),
                    NoKetamine = d.Average(t => t.NoKetamine),
                    Cyclohexanone = d.Average(t => t.Cyclohexanone),
                    MDA = d.Average(t => t.MDA),
                    MDMA = d.Average(t => t.MDMA),
                    Benzoylecgonine = d.Average(t => t.Benzoylecgonine),
                    Cocaine = d.Average(t => t.Cocaine),
                    Cotinine = d.Average(t => t.Cotinine),
                    MonitoringSite = d.Key.MonitoringSite,
                    CityName = d.Key.CityName,
                    AreaName = d.Key.AreaName,
                    AreaID = d.Key.AreaID,
                    Quarter = d.Key.Month
                }).ToListAsync();
            }
            return null;

        }


        public IQueryable<MonitoringSiteView> GetMonitoringSites(Expression<Func<UnionMonitorSite, bool>> expression)
        {
            var query = from company in _dbContext.Company.AsNoTracking()
                        join area in _dbContext.Regions.AsNoTracking() on company.CityID equals area.ParentID
                        join drug in _dbContext.Drug.AsNoTracking() on area.ID equals drug.AreaID 
                        select
                        new UnionMonitorSite
                        {
                            company=company,
                            area=area,
                            drug=drug,
                        };
                            // AreaID = area.ID,
                            //AreaName = area.DisplayName,
                            //MonitoringSite = drugarea == null ? area.DisplayName : drugarea.MonitoringSite,
                            //Latitude = area.Latitude,
                            //Longitude = area.Longitude,
                            //CompanyID=company.ID,
            return query.Where(expression).Select(t=>new MonitoringSiteView() {
                AreaID = t.area.ID,
                AreaName = t.area.DisplayName,
                MonitoringSite = t.drug == null ? t.area.DisplayName : t.drug.MonitoringSite,
                Latitude = t.area.Latitude,
                Longitude = t.area.Longitude,
            });
        }
    }
}
